/**
 * $RCSfile: URLConverter.java,v $
 * $Revision: 1.10 $
 * $Date: 2001/10/13 02:39:26 $
 *
 * Copyright (C) 1999-2001 CoolServlets, Inc. All rights reserved.
 *
 * This software is the proprietary information of CoolServlets, Inc.
 * Use is subject to license terms.
 */

package com.jivesoftware.forum.filter;

import com.jivesoftware.forum.*;

/**
 * A ForumMessageFilter that converts URL's to working HTML web links.
 */
public class URLConverter extends ForumMessageFilter {

    private boolean filteringSubject;
    private boolean filteringBody;
    private boolean newWindowEnabled;

   /**
    * Creates a new filter not associated with a message. This is
    * generally only useful for defining a template filter that other
    * fitlers will be cloned from.
    */
    public URLConverter() {
        filteringSubject = false;
        filteringBody = true;
        newWindowEnabled = false;
    }

    /**
     * Clones a new filter that will have the same properties and that
     * will wrap around the specified message.
     *
     * @param message the ForumMessage to wrap the new filter around.
     */
    public ForumMessageFilter clone(ForumMessage message){
        URLConverter filter = new URLConverter();
        filter.filteringBody = filteringBody;
        filter.filteringSubject = filteringSubject;
        filter.newWindowEnabled = newWindowEnabled;
        filter.message = message;
        return filter;
    }

    public boolean isCacheable() {
        return true;
    }

    //FROM THE FORUMMESSAGE INTERFACE//

    /**
     * Returns the subject of the message with URLs changed to working links if
     * filtering on the subject is enabled.
     *
     * @return the filtered message subject.
     */
    public String getSubject() {
        if (filteringSubject) {
            return convertURL(message.getSubject());
        }
        else return message.getSubject();
    }

    /**
     * Returns the body of the message with URLs changed to working links if
     * filtering on the body is enabled.
     *
     * @return the filtered message body.
     */
    public String getBody() {
        if (filteringBody) {
            return convertURL(message.getBody());
        }
        else return message.getBody();
    }

    //OTHER METHODS//

    /**
     * Returns true if filtering on the subject is enabled.
     *
     * @return true if filtering on the subject is enabled.
     */
    public boolean isFilteringSubject() {
        return filteringSubject;
    }

    /**
     * Enables or disables filtering on the subject.
     *
     * @param filteringSubject toggle value for filtering on subject.
     */
    public void setFilteringSubject(boolean filteringSubject) {
        this.filteringSubject = filteringSubject;
    }

    /**
     * Returns true if filtering on the body is enabled.
     *
     * @return true if filtering on the body is enabled.
     */
    public boolean isFilteringBody() {
        return filteringBody;
    }

    /**
     * Enables or disables filtering on the body.
     *
     * @param filteringBody toggle value for filtering on body.
     */
    public void setFilteringBody(boolean filteringBody) {
        this.filteringBody = filteringBody;
    }

    /**
     * Returns true if URL clicks will open in a new window.
     *
     * @return true if new window mode is enabled.
     */
    public boolean isNewWindowEnabled() {
        return newWindowEnabled;
    }

    /**
     * Enables or disables the new window mode. When active, URL clicks will
     * open in a new window.
     *
     * @param enabled true if new window mode should be enabled.
     */
    public void setNewWindowEnabled(boolean enabled) {
        this.newWindowEnabled = enabled;
    }

    /**
     * This method takes a string which may contain URLs
     * and replaces them with working links.  It does this
     * by adding the html tags <a href> and </a>.
     *
     * @param input the text to be converted.
     * @return the input string with the URLs replaced with links.
     */
    private String convertURL(String input) {
        // Check if the string is null or zero length -- if so, return
        // what was sent in.
        if (input == null || input.length() == 0) {
            return input;
        }
        else {
            StringBuffer buf = new StringBuffer(input.length() + 25);
            char[] chars = input.toCharArray();

            int i = 0, j = 0, oldend = 0;
            int len = input.length();
            char cur;

            // For each URL in the input string:
            while ( ( i=input.indexOf("http://", oldend) ) >= 0 ) {
                j=i+7;
                cur = chars[j];
                while (j < len) {
                    // Is a space?
                    if (cur == ' ') break;
                    // Is html?
                    if (cur == '<') break;
                    // Trying to do a Jive tag?
                    if (cur == '[') break;
                    // Is a Win32 newline?
                    if (cur == '\n') break;
                    // Is Unix newline?
                    if (cur == '\r' && j<len-1 && chars[j+1] == '\n') break;

                    j++;
                    if (j<len) {
                        cur = chars[j];
                    }
                }
                // Check the ending character of the URL. If it's doesn't appear
                // to be valid, then we'll remove that part from the URL.
                char end = chars[j-1];
                if (end=='.' || end==',' || end==')' || end==';' || end=='(' ||
                        end=='-' || end=='*')
                {
                    j--;
                }
                buf.append(chars, oldend, i-oldend);
                buf.append("<a href=\"");
                buf.append(chars, i, j-i);
                buf.append("\"");
                if (newWindowEnabled) {
                    buf.append(" target=\"_blank\">");
                }
                else {
                    buf.append(">");
                }
                buf.append(chars, i, j-i);
                buf.append("</a>");
                oldend = j;
            }
            buf.append(chars, j, len-j);
            return buf.toString();
        }
    }
}
